<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实时通知功能测试</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1000px;
            margin: 50px auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .test-section {
            background: white;
            margin-bottom: 30px;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }
        .test-section h2 {
            margin-top: 0;
            color: #333;
            border-bottom: 2px solid #007bff;
            padding-bottom: 10px;
        }
        button {
            background-color: #007bff;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
            margin-bottom: 10px;
            transition: background-color 0.2s;
        }
        button:hover {
            background-color: #0056b3;
        }
        button:disabled {
            background-color: #6c757d;
            cursor: not-allowed;
        }
        .status-indicator {
            display: inline-block;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 12px;
            font-weight: bold;
            margin-left: 10px;
        }
        .status-connected {
            background-color: #d4edda;
            color: #155724;
        }
        .status-disconnected {
            background-color: #f8d7da;
            color: #721c24;
        }
        .status-connecting {
            background-color: #fff3cd;
            color: #856404;
        }
        .log-container {
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 4px;
            padding: 15px;
            max-height: 300px;
            overflow-y: auto;
            font-family: monospace;
            font-size: 12px;
            margin-top: 15px;
        }
        .log-entry {
            margin-bottom: 5px;
            padding: 2px 0;
        }
        .log-success {
            color: #28a745;
        }
        .log-error {
            color: #dc3545;
        }
        .log-info {
            color: #17a2b8;
        }
        .log-warning {
            color: #ffc107;
        }
        .notification-test {
            background-color: #e7f3ff;
            border: 1px solid #b3d9ff;
            border-radius: 4px;
            padding: 15px;
            margin-top: 15px;
        }
        .notification-test h4 {
            margin-top: 0;
            color: #0066cc;
        }
        .form-group {
            margin-bottom: 15px;
        }
        .form-group label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        .form-group input, .form-group select, .form-group textarea {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }
        .form-group textarea {
            height: 80px;
            resize: vertical;
        }
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-top: 15px;
        }
        .stat-card {
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 4px;
            padding: 15px;
            text-align: center;
        }
        .stat-number {
            font-size: 24px;
            font-weight: bold;
            color: #007bff;
        }
        .stat-label {
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }
    </style>
</head>
<body>
    <h1>🔔 实时通知功能测试</h1>
    
    <div class="test-section">
        <h2>1. WebSocket连接状态</h2>
        <div>
            <button onclick="connectWebSocket()">连接WebSocket</button>
            <button onclick="disconnectWebSocket()">断开连接</button>
            <button onclick="checkConnectionStatus()">检查状态</button>
            <span id="connection-status" class="status-indicator status-disconnected">未连接</span>
        </div>
        <div class="log-container" id="connection-log"></div>
    </div>

    <div class="test-section">
        <h2>2. 通知权限测试</h2>
        <div>
            <button onclick="requestNotificationPermission()">请求通知权限</button>
            <button onclick="checkNotificationPermission()">检查权限状态</button>
            <button onclick="testNotification()">发送测试通知</button>
            <span id="permission-status" class="status-indicator">未知</span>
        </div>
        <div class="log-container" id="permission-log"></div>
    </div>

    <div class="test-section">
        <h2>3. 模拟通知消息</h2>
        <div class="notification-test">
            <h4>创建自定义通知</h4>
            <div class="form-group">
                <label>通知标题:</label>
                <input type="text" id="notification-title" value="测试通知" placeholder="输入通知标题">
            </div>
            <div class="form-group">
                <label>通知内容:</label>
                <textarea id="notification-content" placeholder="输入通知内容">这是一个测试通知，用于验证实时通知功能是否正常工作。</textarea>
            </div>
            <div class="form-group">
                <label>通知类型:</label>
                <select id="notification-type">
                    <option value="info">信息</option>
                    <option value="success">成功</option>
                    <option value="warning">警告</option>
                    <option value="error">错误</option>
                    <option value="ticket">工单</option>
                    <option value="system">系统</option>
                </select>
            </div>
            <div class="form-group">
                <label>优先级:</label>
                <select id="notification-priority">
                    <option value="low">低</option>
                    <option value="normal" selected>普通</option>
                    <option value="high">高</option>
                    <option value="urgent">紧急</option>
                </select>
            </div>
            <div class="form-group">
                <label>分类:</label>
                <select id="notification-category">
                    <option value="general">一般</option>
                    <option value="ticket">工单</option>
                    <option value="system">系统</option>
                    <option value="user">用户</option>
                </select>
            </div>
            <button onclick="sendCustomNotification()">发送自定义通知</button>
            <button onclick="sendRandomNotification()">发送随机通知</button>
        </div>
        <div class="log-container" id="notification-log"></div>
    </div>

    <div class="test-section">
        <h2>4. 通知统计</h2>
        <div class="stats-grid">
            <div class="stat-card">
                <div class="stat-number" id="total-notifications">0</div>
                <div class="stat-label">总通知数</div>
            </div>
            <div class="stat-card">
                <div class="stat-number" id="unread-notifications">0</div>
                <div class="stat-label">未读通知</div>
            </div>
            <div class="stat-card">
                <div class="stat-number" id="desktop-notifications">0</div>
                <div class="stat-label">桌面通知</div>
            </div>
            <div class="stat-card">
                <div class="stat-number" id="websocket-messages">0</div>
                <div class="stat-label">WebSocket消息</div>
            </div>
        </div>
        <div class="log-container" id="stats-log"></div>
    </div>

    <div class="test-section">
        <h2>5. 功能说明</h2>
        <div style="line-height: 1.6;">
            <h3>✅ 已实现的功能:</h3>
            <ul>
                <li><strong>WebSocket服务</strong>: 自动连接、重连机制、连接状态管理</li>
                <li><strong>消息处理</strong>: 支持多种消息类型（通知、工单更新、用户上线、系统消息）</li>
                <li><strong>桌面通知</strong>: 浏览器原生通知API，支持权限管理</li>
                <li><strong>已读状态同步</strong>: 本地状态管理，服务器同步</li>
                <li><strong>通知中心</strong>: 完整的通知管理界面</li>
                <li><strong>实时更新</strong>: 导航栏显示未读计数</li>
            </ul>
            
            <h3>🔧 技术特性:</h3>
            <ul>
                <li><strong>自动重连</strong>: 网络断开时自动尝试重连</li>
                <li><strong>消息队列</strong>: 离线时缓存消息，上线后处理</li>
                <li><strong>权限管理</strong>: 优雅的权限请求和状态处理</li>
                <li><strong>状态持久化</strong>: 通知数据本地存储</li>
                <li><strong>类型安全</strong>: 完整的TypeScript类型定义</li>
            </ul>
            
            <h3>📱 使用方法:</h3>
            <ol>
                <li>确保后端WebSocket服务运行在 <code>ws://localhost:9090/ws/notifications</code></li>
                <li>登录系统后，通知服务会自动启动</li>
                <li>点击导航栏的铃铛图标查看通知</li>
                <li>系统会自动显示桌面通知（需要用户授权）</li>
                <li>通知支持点击跳转到相关页面</li>
            </ol>
        </div>
    </div>

    <script>
        let ws = null;
        let stats = {
            totalNotifications: 0,
            unreadNotifications: 0,
            desktopNotifications: 0,
            websocketMessages: 0
        };

        // WebSocket连接
        function connectWebSocket() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                log('connection', 'WebSocket已连接', 'warning');
                return;
            }

            log('connection', '正在连接WebSocket...', 'info');
            updateConnectionStatus('connecting');

            try {
                ws = new WebSocket('ws://localhost:9090/ws/notifications');
                
                ws.onopen = function(event) {
                    log('connection', '✅ WebSocket连接成功', 'success');
                    updateConnectionStatus('connected');
                    
                    // 发送认证信息
                    sendAuth();
                };
                
                ws.onmessage = function(event) {
                    stats.websocketMessages++;
                    updateStats();
                    
                    try {
                        const data = JSON.parse(event.data);
                        log('connection', `📨 收到消息: ${JSON.stringify(data)}`, 'info');
                        handleWebSocketMessage(data);
                    } catch (error) {
                        log('connection', `❌ 解析消息失败: ${error.message}`, 'error');
                    }
                };
                
                ws.onclose = function(event) {
                    log('connection', `🔌 连接关闭: ${event.code} ${event.reason}`, 'warning');
                    updateConnectionStatus('disconnected');
                };
                
                ws.onerror = function(error) {
                    log('connection', `❌ 连接错误: ${error}`, 'error');
                    updateConnectionStatus('disconnected');
                };
                
            } catch (error) {
                log('connection', `❌ 连接失败: ${error.message}`, 'error');
                updateConnectionStatus('disconnected');
            }
        }

        function disconnectWebSocket() {
            if (ws) {
                ws.close(1000, '主动断开');
                ws = null;
                log('connection', '🔌 主动断开WebSocket连接', 'info');
                updateConnectionStatus('disconnected');
            }
        }

        function checkConnectionStatus() {
            if (!ws) {
                log('connection', 'WebSocket未初始化', 'warning');
                return;
            }
            
            const states = {
                0: 'CONNECTING',
                1: 'OPEN',
                2: 'CLOSING',
                3: 'CLOSED'
            };
            
            log('connection', `连接状态: ${states[ws.readyState]}`, 'info');
        }

        function sendAuth() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                const authData = {
                    type: 'auth',
                    token: 'test-token-' + Date.now()
                };
                ws.send(JSON.stringify(authData));
                log('connection', '🔐 发送认证信息', 'info');
            }
        }

        function handleWebSocketMessage(data) {
            switch (data.type) {
                case 'notification':
                    handleNotificationMessage(data.payload);
                    break;
                case 'auth_success':
                    log('connection', '✅ 认证成功', 'success');
                    break;
                case 'auth_failed':
                    log('connection', '❌ 认证失败', 'error');
                    break;
                default:
                    log('connection', `📨 未知消息类型: ${data.type}`, 'warning');
            }
        }

        function handleNotificationMessage(payload) {
            stats.totalNotifications++;
            updateStats();
            
            log('notification', `🔔 收到通知: ${payload.title}`, 'success');
            
            // 显示桌面通知
            showDesktopNotification(payload);
        }

        // 通知权限管理
        function requestNotificationPermission() {
            if (!('Notification' in window)) {
                log('permission', '❌ 浏览器不支持桌面通知', 'error');
                return;
            }

            Notification.requestPermission().then(permission => {
                log('permission', `权限状态: ${permission}`, permission === 'granted' ? 'success' : 'warning');
                updatePermissionStatus(permission);
            });
        }

        function checkNotificationPermission() {
            if (!('Notification' in window)) {
                log('permission', '❌ 浏览器不支持桌面通知', 'error');
                updatePermissionStatus('not-supported');
                return;
            }

            const permission = Notification.permission;
            log('permission', `当前权限状态: ${permission}`, permission === 'granted' ? 'success' : 'warning');
            updatePermissionStatus(permission);
        }

        function testNotification() {
            if (Notification.permission === 'granted') {
                const notification = new Notification('测试通知', {
                    body: '这是一个测试通知，用于验证桌面通知功能',
                    icon: '/favicon.ico',
                    tag: 'test-notification'
                });

                notification.onclick = () => {
                    log('permission', '🖱️ 通知被点击', 'info');
                    notification.close();
                };

                stats.desktopNotifications++;
                updateStats();
                log('permission', '✅ 桌面通知已发送', 'success');
            } else {
                log('permission', '❌ 没有通知权限', 'error');
            }
        }

        // 自定义通知
        function sendCustomNotification() {
            const title = document.getElementById('notification-title').value;
            const content = document.getElementById('notification-content').value;
            const type = document.getElementById('notification-type').value;
            const priority = document.getElementById('notification-priority').value;
            const category = document.getElementById('notification-category').value;

            const notification = {
                id: 'custom-' + Date.now(),
                title: title,
                content: content,
                type: type,
                priority: priority,
                category: category,
                timestamp: Date.now(),
                sender: {
                    username: '测试用户',
                    id: 1
                }
            };

            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.send(JSON.stringify({
                    type: 'notification',
                    payload: notification
                }));
                log('notification', `📤 发送自定义通知: ${title}`, 'success');
            } else {
                log('notification', '❌ WebSocket未连接', 'error');
            }
        }

        function sendRandomNotification() {
            const notifications = [
                {
                    title: '新工单创建',
                    content: '工单 #12345 已创建',
                    type: 'ticket',
                    priority: 'normal',
                    category: 'ticket'
                },
                {
                    title: '系统维护通知',
                    content: '系统将在今晚22:00进行维护',
                    type: 'system',
                    priority: 'high',
                    category: 'system'
                },
                {
                    title: '用户上线',
                    content: '张三 已上线',
                    type: 'user',
                    priority: 'low',
                    category: 'user'
                },
                {
                    title: '工单状态变更',
                    content: '工单 #12345 状态变更为"处理中"',
                    type: 'ticket',
                    priority: 'normal',
                    category: 'ticket'
                }
            ];

            const randomNotification = notifications[Math.floor(Math.random() * notifications.length)];
            randomNotification.id = 'random-' + Date.now();
            randomNotification.timestamp = Date.now();
            randomNotification.sender = {
                username: '系统',
                id: 0
            };

            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.send(JSON.stringify({
                    type: 'notification',
                    payload: randomNotification
                }));
                log('notification', `📤 发送随机通知: ${randomNotification.title}`, 'success');
            } else {
                log('notification', '❌ WebSocket未连接', 'error');
            }
        }

        function showDesktopNotification(payload) {
            if (Notification.permission === 'granted') {
                const notification = new Notification(payload.title, {
                    body: payload.content,
                    icon: '/favicon.ico',
                    tag: payload.id,
                    data: payload
                });

                notification.onclick = () => {
                    log('notification', `🖱️ 通知被点击: ${payload.title}`, 'info');
                    notification.close();
                };

                stats.desktopNotifications++;
                updateStats();
            }
        }

        // 状态更新
        function updateConnectionStatus(status) {
            const statusElement = document.getElementById('connection-status');
            statusElement.className = 'status-indicator';
            
            switch (status) {
                case 'connected':
                    statusElement.textContent = '已连接';
                    statusElement.classList.add('status-connected');
                    break;
                case 'connecting':
                    statusElement.textContent = '连接中';
                    statusElement.classList.add('status-connecting');
                    break;
                case 'disconnected':
                default:
                    statusElement.textContent = '未连接';
                    statusElement.classList.add('status-disconnected');
                    break;
            }
        }

        function updatePermissionStatus(permission) {
            const statusElement = document.getElementById('permission-status');
            statusElement.className = 'status-indicator';
            
            switch (permission) {
                case 'granted':
                    statusElement.textContent = '已授权';
                    statusElement.classList.add('status-connected');
                    break;
                case 'denied':
                    statusElement.textContent = '已拒绝';
                    statusElement.classList.add('status-disconnected');
                    break;
                case 'default':
                    statusElement.textContent = '未请求';
                    statusElement.classList.add('status-connecting');
                    break;
                case 'not-supported':
                    statusElement.textContent = '不支持';
                    statusElement.classList.add('status-disconnected');
                    break;
                default:
                    statusElement.textContent = '未知';
                    break;
            }
        }

        function updateStats() {
            document.getElementById('total-notifications').textContent = stats.totalNotifications;
            document.getElementById('unread-notifications').textContent = stats.unreadNotifications;
            document.getElementById('desktop-notifications').textContent = stats.desktopNotifications;
            document.getElementById('websocket-messages').textContent = stats.websocketMessages;
        }

        // 日志记录
        function log(type, message, level = 'info') {
            const logContainer = document.getElementById(type + '-log');
            const logEntry = document.createElement('div');
            logEntry.className = `log-entry log-${level}`;
            logEntry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
            logContainer.appendChild(logEntry);
            logContainer.scrollTop = logContainer.scrollHeight;
        }

        // 页面加载时初始化
        window.onload = function() {
            checkNotificationPermission();
            updateStats();
            log('connection', '页面加载完成，可以开始测试', 'info');
        };
    </script>
</body>
</html>
